package com.sansan.qiangji.controller.warehouse;

import com.sansan.qiangji.VO.warehouse.stackerTaskOutVO.StackerTaskOutVO;
import com.sansan.qiangji.config.RedisConfig;
import com.sansan.qiangji.enums.RedisLockKeyEnum;
import com.sansan.qiangji.enums.ResultEnum;
import com.sansan.qiangji.exception.ServiceException;
import com.sansan.qiangji.form.warehouse.ProductUnbindingStockForm;
import com.sansan.qiangji.form.warehouse.PullOrderDetailAddForm;
import com.sansan.qiangji.form.warehouse.PullOrderDetailEditForm;
import com.sansan.qiangji.form.warehouse.PullOrderDetailListForm;
import com.sansan.qiangji.realize.warehouse.PullOrderDetailReal;
import com.sansan.qiangji.resultVO.ResultVO;
import com.sansan.qiangji.task.AsyncTask;
import com.sansan.qiangji.utils.RedisLockUtil;
import com.sansan.qiangji.utils.ResultVOUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;

import javax.validation.Valid;
import java.util.Objects;
import java.util.UUID;

@CrossOrigin()
@RestController
@Slf4j
@RequestMapping("/pullOrderDetail")
public class PullOrderDetailController {
    @Autowired
    private PullOrderDetailReal pullOrderDetailReal;
    @Autowired
    private RedisConfig redisConfig;
    @Autowired
    private AsyncTask asyncTask;

    @PostMapping("/addPullOrderDetail")
    public ResultVO<Object> addPullOrderDetail(@Valid @RequestBody PullOrderDetailAddForm pullOrderDetailAddForm, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            log.error("【入库单详情新增】参数不正确，pullOrderDetailAddForm={}", pullOrderDetailAddForm);
            throw new ServiceException(ResultEnum.PARAM_ERROR.getCode(), Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        pullOrderDetailReal.addPullOrderDetail(pullOrderDetailAddForm);
        return ResultVOUtil.success(null);
    }

    @PostMapping("/getPullOrderDetailList")
    public ResultVO<Object> getPullOrderDetailList(@Valid @RequestBody PullOrderDetailListForm form, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            log.error("【入库单详情查询】参数不正确，pullOrderDetailAddForm={}", form);
            throw new ServiceException(ResultEnum.PARAM_ERROR.getCode(), Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        return ResultVOUtil.success(pullOrderDetailReal.pullOrderDetailList(form));
    }

    @PostMapping("/editPullOrderDetail")
    public ResultVO<Object> editPullOrderDetail(@Valid @RequestBody PullOrderDetailEditForm pullOrderDetailEditForm, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            log.error("【入库单详情修改】参数不正确，pullOrderDetailAddForm={}", pullOrderDetailEditForm);
            throw new ServiceException(ResultEnum.PARAM_ERROR.getCode(), Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        pullOrderDetailReal.editPullOrderDetail(pullOrderDetailEditForm);
        return ResultVOUtil.success(null);
    }

    @PostMapping("/deletePullOrderDetail")
    public ResultVO<Object> deletePullOrderDetail(@RequestParam(value = "pullOrderDetailId") Integer pullOrderDetailId) {
        pullOrderDetailReal.deletePullOrderDetail(pullOrderDetailId);
        return ResultVOUtil.success(null);
    }

    @PostMapping("/productUnbindingStock")
    public ResultVO<Object> productUnbindingStock(@Valid @RequestBody ProductUnbindingStockForm form) {
        Jedis jedis = new Jedis(redisConfig.getHost(), redisConfig.getPort());
        String requestId = UUID.randomUUID().toString();
        if (!redisConfig.getPassword().equals("")) {
            jedis.auth(redisConfig.getPassword());
        }
        try {
            StackerTaskOutVO stackerTaskOutVO = new StackerTaskOutVO();
            for (int i = 0; i < 5; i++) {
                if (!RedisLockUtil.tryGetDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId, 5000)) {
                    if (i == 4) {
                        log.error("【任务执行】系统任务繁忙 !");
                        throw new ServiceException(ResultEnum.STACKER_TASK_BUSY);
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (Exception ignored) {
                    }
                    continue;
                }
                stackerTaskOutVO = pullOrderDetailReal.productUnbindingStock(form);
                asyncTask.pullProduct(stackerTaskOutVO.getStackerTaskOutCode());
                break;
            }
            jedis.close();
            RedisLockUtil.releaseDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId);
            return ResultVOUtil.success(stackerTaskOutVO);
        } catch (Exception e) {
            jedis.close();
            RedisLockUtil.releaseDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId);
            throw e;
        }
    }

    @PostMapping("/stackerTaskOutContinue")
    public ResultVO<Object> stackerTaskOutContinue(@RequestParam(value = "stackerTaskOutCode") String stackerTaskOutCode,
                                                   @RequestParam(value = "stackerTaskOutPace") String stackerTaskOutPace) {
        Jedis jedis = new Jedis(redisConfig.getHost(), redisConfig.getPort());
        String requestId = UUID.randomUUID().toString();
        if (!redisConfig.getPassword().equals("")) {
            jedis.auth(redisConfig.getPassword());
        }
        try {
            for (int i = 0; i < 5; i++) {
                if (!RedisLockUtil.tryGetDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId, 5000)) {
                    if (i == 4) {
                        log.error("【任务执行】系统任务繁忙 !");
                        throw new ServiceException(ResultEnum.STACKER_TASK_BUSY);
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (Exception ignored) {
                    }
                    continue;
                }
                pullOrderDetailReal.stackerTaskOutContinue(stackerTaskOutCode, stackerTaskOutPace);
                asyncTask.pullProduct(stackerTaskOutCode);
                break;
            }
            jedis.close();
            RedisLockUtil.releaseDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId);
            return ResultVOUtil.success(null);
        } catch (Exception e) {
            jedis.close();
            RedisLockUtil.releaseDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId);
            throw e;
        }
    }
}

